// 管理SQLite3数据库
export class ManageSqlite3 {
    // sqlite3对象
    private sqlite3 = require('sqlite3');
    // 数据库实体
    private _db: any | object = {};
    constructor() {

    }

    /**
     * 打开数据库
     * @param filename 数据库文件名
     * @param isMemory 是否为内存数据库
     * @return true 打开成功 false 打开失败
     */
    Open(filename: string, isMemory?: boolean) {
        return new Promise((resovlve, reject) => {
            try {
                if (isMemory) {
                    filename = ":memory:";
                }
                this._db = new this.sqlite3.Database(filename, (err: object) => {
                    console.error(err);
                    if (err) {
                        reject(false);
                    } else {
                        resovlve(true);
                    }
                })
            } catch (err) {
                reject(false);
            }
        });
    }

    /**
     * 执行同语句批量数据
     * @param sql 带参数sql语句
     * @param values 变量数组
     * @returns true 全部执行成功 false 全部执行失败
     * @see 本函数为同一条sql语句，不通变量多次执行使用
     * @example
     * <br>
     * <br>
     * let sql = "insert into testtable values(?,?,?,?)";<br>
     * let values = [1,2,3,4];<br>
     * RunBatch(sql,values)<br>
     * .then(()=>{<br>
     * //执行成功代码<br>
     * })<br>
     * .catch(()=>{<br>
     * //执行错误代码<br>
     * })<br>
     * 
     * @example
     * <br>
     * <br>
     * let sql = "insert into testtable values($num1,$num2,$num3,$num4)";<br>
     * let values = [{$num1,$num2,$num3,$num4}];<br>
     * RunBatch(sql,values)<br>
     * .then(()=>{<br>
     * //执行成功代码<br>
     * })<br>
     * .catch(()=>{<br>
     * //执行错误代码<br>
     * })<br>
     */
    RunBatch(sql: string, values: Array<object> | Array<any>) {
        return new Promise((resovlve, reject) => {
            try {
                let stmt = this._db.prepare(sql);
                for (let i = 0; i < values.length; i++) {
                    stmt.run(values[i]);
                }
                stmt.finalize(() => {
                    resovlve(true);
                });
            } catch (err) {
                console.error(err);
                reject(false);
            }
        });
    }

    /**
     * 顺序执行多条sql语句
     * @param sqls sql语句数组
     * 
     */
    // RunSQLS(sqls: Array<string>) {
    //     return new Promise((resovlve, reject) => {
    //         try {
    //             this._db.serialize(() => {
    //                 this._db.serialize(() => {
    //                     for (let i = 0; i < sqls.length; i++) {
    //                         this._db.run(sqls[i]);
    //                     }
    //                 })
    //                 resovlve(true);
    //             });
    //         } catch (err) {
    //             console.error(err);
    //             reject(false);
    //         }
    //     });
    // }

    /**
     * 执行无返回指令
     * @param sql sql语句
     * @param values 变量数组
     * @return true 执行成功 false 执行失败
     */
    Run(sql: string, values?: any) {
        return new Promise((resovlve, reject) => {
            try {
                if (values) {
                    this._db.run(sql, values, (err: object) => {
                        if (err) {
                            reject(false);
                        } else {
                            resovlve(true);
                        }
                    })
                } else {
                    this._db.run(sql, (err: object) => {
                        if (err) {
                            reject(false);
                        } else {
                            resovlve(true);
                        }
                    })
                }
            } catch (err) {
                reject(false);
            }
        });
    }

    /**
     * 开启事务
     * @returns true 成功开始 false 开启事务失败
     */
    BeginTran() {
        return new Promise((resovlve, reject) => {
            try {
                this.Run('BEGIN TRANSACTION')
                    .then(() => {
                        resovlve(true);
                    })
                    .catch(() => {
                        reject(false);
                    })
            } catch (err) {
                reject(false);
            }
        });
    }

    /**
     * 提交事务
     * @returns true 成功提交 false 提交事务失败
     */
    CommitTran() {
        return new Promise((resovlve, reject) => {
            try {
                this.Run('COMMIT TRANSACTION')
                    .then(() => {
                        resovlve(true);
                    })
                    .catch(() => {
                        reject(false);
                    })
            } catch (err) {
                reject(false);
            }
        });
    }

    /**
     * 回滚事务
     * @returns true 成功回滚 false 回滚失败
     */
    RollbackTran() {
        return new Promise((resovlve, reject) => {
            try {
                this.Run('ROLLBACK TRANSACTION')
                    .then(() => {
                        resovlve(true);
                    })
                    .catch(() => {
                        reject(false);
                    })
            } catch (err) {
                reject(false);
            }
        });
    }

    /**
     * 查找数据
     * @param sql sql语句
     * @param isOne 是否返回第一条数据
     * @return 返回结果集数组，如果没有数据返回[]
     */
    Find(sql: string, isOne?: boolean) {
        return new Promise((resovlve, reject) => {
            try {
                if (isOne) {
                    this._db.get(sql, (err: object, rows: any) => {
                        if (err) {
                            reject([]);
                        } else {
                            if (!Array.isArray(rows)) {
                                rows = [rows];
                            }
                            resovlve(rows);
                        }
                    })
                } else {
                    this._db.all(sql, (err: object, rows: any) => {
                        if (err) {
                            reject([]);
                        } else {
                            resovlve(rows);
                        }
                    })
                }
            } catch (err) {
                reject([]);
            }
        });
    }

    /**
     * 关闭数据库
     * @returns true 关闭成功 false关闭失败
     */
    Close() {
        return new Promise((resovlve, reject) => {
            try {
                this._db.close((err: object) => {
                    if (err) {
                        reject(false);
                    } else {
                        resovlve(true);
                    }
                })
            } catch (err) {
                reject(false);
            }
        });
    }
}